调试器可视化工具概述

您所在的位置:网站首页 pyqt 打包二次调用 调试器可视化工具概述

调试器可视化工具概述

2023-05-26 04:49| 来源: 网络整理| 查看: 265

创建 Visual Studio 调试器可视化工具 项目 05/24/2023

调试器可视化工具是 Visual Studio 的一项功能,在调试会话期间为特定 .NET 类型的变量或对象提供自定义可视化效果。

可通过将鼠标悬停在变量上时出现的 数据提示 访问调试器可视化工具,或者从 “自动”、“ 局部变量”和“ 监视 ”窗口访问:

入门

按照入门部分中的创建扩展项目部分进行操作。

然后,添加一个扩展 DebuggerVisualizerProvider 的类, VisualStudioContribution 并向其应用 特性:

/// /// Debugger visualizer provider class for . /// [VisualStudioContribution] internal class StringDebuggerVisualizerProvider : DebuggerVisualizerProvider { /// /// Initializes a new instance of the class. /// /// Extension instance. /// Extensibility object. public RegexMatchDebuggerVisualizerProvider(RegexMatchVisualizerExtension extension, VisualStudioExtensibility extensibility) : base(extension, extensibility) { } /// public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new("My string visualizer", typeof(string)); /// public override async Task CreateVisualizerAsync(VisualizerTarget visualizerTarget, CancellationToken cancellationToken) { string targetObjectValue = await visualizerTarget.ObjectSource.RequestDataAsync(jsonSerializer: null, cancellationToken); return new MyStringVisualizerControl(targetObjectValue); } }

前面的代码定义了一个新的调试器可视化工具,该可视化工具适用于 类型的 string对象:

属性 DebuggerVisualizerProviderConfiguration 定义可视化工具显示名称和支持的 .NET 类型。 CreateVisualizerAsync当用户请求显示特定值的调试器可视化工具时,Visual Studio 会调用 方法。 CreateVisualizerAsyncVisualizerTarget使用 对象检索要可视化的值,并将其传递给自定义远程用户控件, (引用远程 UI 文档) 。 然后返回远程用户控件,并在 Visual Studio 的弹出窗口中显示。 可视化工具对象源

可视化工具对象源是由调试器在正在调试的进程中加载的 .NET 类。 调试器可视化工具可以使用 公开 VisualizerTarget.ObjectSource的方法从可视化工具对象源中检索数据。

默认可视化工具对象源允许调试器可视化工具通过调用 RequestDataAsync(JsonSerializer?, CancellationToken) 方法检索要可视化的对象的值。 默认可视化工具对象源使用 Newtonsoft.Json 序列化值,VisualStudio.Extensibility 库也使用 Newtonsoft.Json 进行反序列化。 或者,可以使用 RequestDataAsync(CancellationToken) 作为 检索序列化的值 JToken。

如果要可视化 Newtonsoft.Json 本机支持的 .NET 类型,或者想要可视化自己的类型,并且可以使其可序列化,则前面的说明足以创建简单的调试器可视化工具。 如果想要支持更复杂的类型或使用更高级的功能,请继续阅读。

使用自定义可视化工具对象源

如果 Newtonsoft.Json 无法自动序列化要可视化的类型,则可以创建自定义可视化工具对象源来处理序列化。

创建面向 netstandard2.0的新 .NET 类库项目。 例如,可以面向更具体的 .NET Framework 或 .NET (版本,net472或者net6.0根据需要) 序列化要可视化的对象。 添加对 Microsoft.VisualStudio.DebuggerVisualizers 版本 17.6 或更高版本的包引用。 添加一个扩展 VisualizerObjectSource 类,并重写 GetData 将 的 target 序列化值写入 outgoingData 流。 public class MyObjectSource : VisualizerObjectSource { /// public override void GetData(object target, Stream outgoingData) { MySerializableType result = Convert(match); SerializeAsJson(outgoingData, result); } private static MySerializableType Convert(object target) { // Add your code here to convert target into a type serializable by Newtonsoft.Json ... } } 使用自定义序列化

可以使用 VisualizerObjectSource.SerializeAsJson 方法将使用 Newtonsoft.Json 的对象序列化为 , Stream 而无需向库添加对 Newtonsoft.Json 的引用。 调用 SerializeAsJson 将通过反射将 Newtonsoft.Json 程序集的版本加载到正在调试的进程中。

如果需要引用 Newtonsoft.Json,则应使用包引用 Microsoft.VisualStudio.Extensibility.Sdk 的相同版本,但最好使用 DataContract 和 DataMember 属性来支持对象序列化,而不是依赖于 Newtonsoft.Json 类型。

或者,可以实现自己的自定义序列化 (例如二进制序列化) 直接写入 。outgoingData

将可视化工具对象源 DLL 添加到扩展

修改向可视化工具对象源库项目添加 ProjectReference 的扩展.csproj文件,以确保在打包扩展之前生成可视化工具对象源库。

此外,将包含 Content 可视化工具对象源库 DLL 的项添加到 netstandard2.0 扩展的子文件夹中。

PreserveNewest

或者,如果生成面向 .NET Framework 或 .NET 的可视化工具对象源库,则可以使用 net4.6.2netcoreapp 或 子文件夹。 你甚至可以包含具有不同版本的可视化工具对象源库的所有三个子文件夹,但最好仅面向 netstandard2.0 。

应尝试最大程度地减少可视化工具对象源库 DLL 的依赖项数。 如果可视化工具对象源库具有除 Microsoft.VisualStudio.DebuggerVisualizer 以外的依赖项和库,这些依赖项已保证在正在调试的进程中加载,请确保还将这些 DLL 文件包含在与可视化工具对象源库 DLL 相同的子文件夹中。

更新调试器可视化工具提供程序以使用自定义可视化工具对象源

然后,可以更新 DebuggerVisualizerProviderConfiguration 配置以引用自定义可视化工具对象源:

public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new("My visualizer", typeof(TypeToVisualize)) { VisualizerObjectSourceType = new(typeof(MyObjectSource)), }; public override async Task CreateVisualizerAsync(VisualizerTarget visualizerTarget, CancellationToken cancellationToken) { MySerializableType result = await visualizerTarget.ObjectSource.RequestDataAsync(jsonSerializer: null, cancellationToken); return new MyVisualizerUserControl(result); } 处理大型和复杂对象

如果无法通过对 的单个无参数调用 RequestDataAsync从可视化工具对象源检索数据,则可以通过调用 RequestDataAsync(TMessage, JsonSerializer?, CancellationToken) 多次并将不同的消息发送到可视化工具对象源来与可视化工具对象源执行更复杂的 消息 交换。 消息和响应均由 VisualStudio.Extensibility 基础结构使用 Newtonsoft.Json 进行序列化。 的其他重写 RequestDataAsync 允许使用 JToken 对象或实现自定义序列化和反序列化。

可以使用不同的消息实现任何自定义协议,以从可视化工具对象源检索信息。 此功能最常见的用例是将潜在大型对象的检索分解为多个调用,以避免 RequestDataAsync 超时。

下面是一个示例,说明如何一次检索一个可能较大的集合的内容:

for (int i = 0; ; i++) { MySerializableType? collectionEntry = await visualizerTarget.ObjectSource.RequestDataAsync(i, jsonSerializer: null, cancellationToken); if (collectionEntry is null) { break; } observableCollection.Add(collectionEntry); }

上面的代码使用简单索引作为调用的消息 RequestDataAsync 。 相应的可视化工具对象源代码将替代 TransferData 方法 (而不是 GetData) :

public class MyCollectionTypeObjectSource : VisualizerObjectSource { public override void TransferData(object target, Stream incomingData, Stream outgoingData) { var index = (int)DeserializeFromJson(incomingData, typeof(int))!; if (target is MyCollectionType collection && index < collection.Count) { var result = Convert(collection[index]); SerializeAsJson(outgoingData, result); } else { SerializeAsJson(outgoingData, null); } } private static MySerializableType Convert(object target) { // Add your code here to convert target into a type serializable by Newtonsoft.Json ... } }

上面的可视化工具对象源利用 VisualizerObjectSource.DeserializeFromJson 方法反序列化可视化工具提供程序从 incomingData发送的消息。

实现与可视化工具对象源执行复杂消息交互的调试器可视化工具提供程序时,通常最好将 传递给 VisualizerTarget 可视化工具, RemoteUserControl 以便在加载控件时以异步方式进行消息交换。 传递 VisualizerTarget 还允许将消息发送到可视化工具对象源,以便根据用户与可视化工具 UI 的交互检索数据。

public override Task CreateVisualizerAsync(VisualizerTarget visualizerTarget, CancellationToken cancellationToken) { return Task.FromResult(new MyVisualizerUserControl(visualizerTarget)); } internal class MyVisualizerUserControl : RemoteUserControl { private readonly VisualizerTarget visualizerTarget; public MyVisualizerUserControl(VisualizerTarget visualizerTarget) : base(new MyDataContext()) { this.visualizerTarget = visualizerTarget; } public override async Task ControlLoadedAsync(CancellationToken cancellationToken) { // Start querying the VisualizerTarget here ... } ... 更新可视化对象值

如果 VisualizerTarget.IsTargetReplaceable 为 true,则调试器可视化工具可以使用 ReplaceTargetObjectAsync 方法更新正在调试的进程中可视化对象的值。

可视化工具对象源必须重写 CreateReplacementObject 方法:

public override object CreateReplacementObject(object target, Stream incomingData) { // Use DeserializeFromJson to read from incomingData // the new value of the object being visualized ... return newValue; } 后续步骤

试用示例 RegexMatchDebugVisualizer ,了解这些技术在操作中。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3